package com.bxait.toymail.product.service.impl;

import com.bxait.com.constant.ProductConstant;
import com.bxait.com.exception.BizCodeEnum;
import com.bxait.com.exception.product.CheckOutException;
import com.bxait.com.utils.PageUtils;
import com.bxait.com.utils.Query;
import com.bxait.com.vo.product.AttrRespVo;
import com.bxait.com.vo.product.AttrVo;
import com.bxait.toymail.product.entity.AttrAttrgroupRelationEntity;
import com.bxait.toymail.product.entity.AttrGroupEntity;
import com.bxait.toymail.product.entity.CategoryEntity;
import com.bxait.toymail.product.service.*;
import com.bxait.toymail.product.utils.CateGoryCheck;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.bxait.toymail.product.dao.AttrDao;
import com.bxait.toymail.product.entity.AttrEntity;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {


    @Resource
    @Qualifier("attrAttrgroupRelationService")
    AttrAttrgroupRelationService attrAttrgroupRelationService;

    @Resource
    @Qualifier("attrGroupService")
    AttrGroupService attrGroupService;

    @Resource
    @Qualifier("categoryService")
    CategoryService categoryService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long cateLogId, String attrType) {

        // 1.构造查询参数
        QueryWrapper<AttrEntity> wrapper
                                = new QueryWrapper<>();
        // 2.如果需要查询的类型是base那就是查询基本属性(也就是属于spu的一些属性值),如果查询销售属性就是查询销售属性(也就是一些sku的一些属性值)
        wrapper.eq("attr_type","base".equalsIgnoreCase(attrType)? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode():ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());

        // 3.校验一下这个三级分类
        if(!CateGoryCheck.checkCateLogId(cateLogId)){
            throw  new CheckOutException(BizCodeEnum.VALID_CHECKOUT_EXCEPTION.getMsg());
        }

        // 4.如果cateLogId不等于0,就算是要查指定商品分类下的属性信息
        if(cateLogId!=0){
            wrapper.eq("catelog_id",cateLogId);
        }

        // 4.拼接模糊查询的条件
        String key = (String) params.get("key");
        if(StringUtils.isNotBlank(key)){
            wrapper.and(item->{
                item.eq("attr_id",key).or().like("attr_name",key);
            });
        }

        // 5.构造出查询的商品属性信息
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                wrapper
        );

        PageUtils pageUtils  =  new PageUtils(page);


        // 6.构造这样的数据进行返回是不够的,还需要返回当前属性所属的分类的完整路径,如果这个属性的类型是基本属性类型,还需要返回属性的分组的名称
        List<AttrEntity> records = page.getRecords();


        List<AttrRespVo> collect = records.stream().map(attrEntity -> {
            AttrRespVo attrRespVo = new AttrRespVo();
            BeanUtils.copyProperties(attrEntity, attrRespVo);
        // 7.给当前要返回的属性设置属性分组信息,需要判断销售属性不需要设置属性分组信息的,因为销售属性没有属性分组信息
            if ("base".equalsIgnoreCase(attrType)) {
                QueryWrapper<AttrAttrgroupRelationEntity> queryWrapper =
                        new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId());
                AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationService.getOne(queryWrapper);
                if (relationEntity != null) {
                    AttrGroupEntity attrGroupEntity = attrGroupService.getById(relationEntity.getAttrGroupId());
                    attrRespVo.setAttrName(attrGroupEntity.getAttrGroupName());
                }

            }
        // 8.设置三级分类的信息
            CategoryEntity categoryEntity = categoryService.getById(cateLogId);
            if (categoryEntity != null) {
                attrRespVo.setCateLogName(categoryEntity.getName());
            }
            List<Long> parentPath = categoryService.findParentPath(cateLogId, new ArrayList<Long>());

            attrRespVo.setCateLogPath(new Long[parentPath.size()]);

            return attrRespVo;
        }).collect(Collectors.toList());


        pageUtils.setList(collect);

        return pageUtils;
    }

    /**
     * @param attr
     * @==============History===============<br/>
     * @Description // TODO  保存属性信息,以及属性分组信息
     * @Date 2023/3/18 2023/3/18
     * @Author < a href="2277411582@qq.com">chen</ a>
     * @return [com.bxait.com.vo.product.AttrVo]
     */
    @Override
    @Transactional
    public void saveAttr(AttrVo attr) {
        // 1.保存属性信息
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr,attrEntity);
        this.save(attrEntity);
        // 2.如果是基本属性,需要保存属性和属性分组信息的关联信息
        Integer attrType = attr.getAttrType();
        if(attrType.equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) && attrType != null){
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(attrEntity.getAttrId());
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrSort(0);
            attrAttrgroupRelationService.save(relationEntity);
        }
    }

    /**
     * @param attrId
     * @==============History===============<br/>
     * @Description // TODO   根据属性id,获取属性的详情信息
     * @Date 2023/3/18 2023/3/18
     * @Author < a href="2277411582@qq.com">chen</ a>
     * @return [java.lang.Long]
     */
    @Override
    public AttrRespVo getAttrInfo(Long attrId) {

        AttrRespVo attrRespVo = new AttrRespVo();
        AttrEntity attrEntity = this.getById(attrId);

        BeanUtils.copyProperties(attrEntity,attrRespVo);

        // 1.设置商品分类信息
        Long cateLogId = attrEntity.getCatelogId();
        List<Long> parentPath = categoryService.findParentPath(cateLogId, new ArrayList<Long>());
        attrRespVo.setCateLogPath(new Long[parentPath.size()]);
        CategoryEntity categoryEntity = categoryService.getById(cateLogId);

        if(categoryEntity != null){
            attrRespVo.setCateLogName(categoryEntity.getName());
        }

        // 2.设置当前属性的分组的信息
        if(attrEntity.getAttrType().equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())){

           AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationService.getOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));

           if(relationEntity != null){
               attrRespVo.setAttrGroupId(relationEntity.getAttrGroupId());
               AttrGroupEntity groupEntity = attrGroupService.getById(relationEntity.getAttrGroupId());
               attrRespVo.setGroupName(groupEntity.getAttrGroupName());
           }

        }
        return attrRespVo;
    }

    /**
     * @param attr
     * @==============History===============<br/>
     * @Description // TODO  修改属性,及其属性分组信息
     * @Date 2023/3/18 2023/3/18 
     * @Author < a href="2277411582@qq.com">chen</ a>
     * @return [com.bxait.com.vo.product.AttrVo]
     */
    @Transactional
    @Override
    public void updateAttr(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr,attrEntity);
        // 1.修改属性信息
        this.updateById(attrEntity);
        // 2.查询当前属性是否有属性分组信息,如果有就是更新,如果没有就是新增
        if(attr.getAttrType().equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())){
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(attr.getAttrId());
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            int count = attrAttrgroupRelationService.count(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
            if(count > 0){
                attrAttrgroupRelationService.update(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id",attr.getAttrId()));
            }else{
                attrAttrgroupRelationService.save(relationEntity);
            }
        }
    }

    /***
     * @param attrGroupId
     * @==============History===============<br/>
     * @Description // TODO  获取当前属性分组的所以属性信息
     * @Date 2023/3/18 2023/3/18
     * @Author < a href="2277411582@qq.com">chen</ a>
     * @return [java.lang.Long]
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrGroupId) {

        // 1.在关联表中获取到当前属性分组关联的所以的属性的id
        List<AttrAttrgroupRelationEntity> relationEntities
                                         = attrAttrgroupRelationService.list(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroupId));

        // 2.获取到所有的属性id
        List<Long> attrIds = relationEntities.stream().map(item -> item.getAttrId()).collect(Collectors.toList());

        // 3.返回这些属性信息
        if(attrIds != null && attrIds.size() > 0){
            return (List<AttrEntity>) this.listByIds(attrIds);
        }
        return new ArrayList<>();
    }

    /**
     * @param params
 * @param attrGroupId
     * @==============History===============<br/>
     * @Description // TODO  获取当前属性分组曦俺没有关联的属性,并且这个属性也没有被别的属性分组所关联
     * @Date 2023/3/19 21:07
     * @Author <a href="qq:2277411582@qq.com">chen</a>
     * @return com.bxait.com.utils.PageUtils
     */
    @Override
    public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrGroupId) {
        // 1.当前属性分组只能关联自己所属分类下的属性
        AttrGroupEntity attrGroupEntity = attrGroupService.getById(attrGroupId);
        Long cateLogId = attrGroupEntity.getCatelogId();
        // 获取当前属性分类下的所有属性分组
        List<AttrGroupEntity> attrGroupEntities
                = attrGroupService.list(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", cateLogId));
        // 收集这个属性分组的id,获取这个属性分组
        List<Long> attrGroupIds = attrGroupEntities.stream().map(item -> item.getAttrGroupId()).collect(Collectors.toList());

        // 获取这个属性分组下的已经被关联的属性,收集这些属性的id
        List<AttrAttrgroupRelationEntity> attrGroupRelationEntities
                = attrAttrgroupRelationService.list(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", attrGroupIds));

        List<Long> attrIds = attrGroupRelationEntities.stream().map(item -> item.getAttrId()).collect(Collectors.toList());


        // 2.当前属性分组只能关联别的属性分组没有关联的属性
        QueryWrapper<AttrEntity> wrapper
                = new QueryWrapper<AttrEntity>().eq("catelog_id", cateLogId).eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
        if(attrIds != null && attrIds.size() > 0){
            // 排除这些已经被关联的属性
            wrapper.notIn("attr_id",attrIds);
        }
        // 3.增加模糊的搜索条件
        String key = (String) params.get("key");
        if(!StringUtils.isEmpty(key)){
            wrapper.and(queryWrapper->{
                queryWrapper.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), wrapper);

        PageUtils pageUtils = new PageUtils(page);
        return pageUtils;
    }

    /*
     * @param attrIds
     * @==============History===============<br/>
     * @Description // TODO 获取当前属性中可以被检索的属性
     * @Date 2023/4/13 22:39
     * @Author <a href="qq:2277411582@qq.com">chen</a>
     * @return java.util.List<java.lang.Long>
     */
    @Override
    public List<Long> selectSearchAttrIds(List<Long> attrIds) {
        return baseMapper.selectSearchAttrIds(attrIds);
    }

}